#!/usr/bin/env python3
import base64
import threading
import pika
import time
import json
import cv2
import os
import numpy
from subprocess import Popen, PIPE


class RTSCapture(cv2.VideoCapture):
    """Real Time Streaming Capture.
    这个类必须使用 RTSCapture.create 方法创建，请不要直接实例化
    """

    _cur_frame = None
    _reading = False
    schemes = ["rtsp://", "rtmp://"] #用于识别实时流

    @staticmethod
    def create(url, *schemes):
        """实例化&初始化
        rtscap = RTSCapture.create("rtsp://example.com/live/1")
        or
        rtscap = RTSCapture.create("http://example.com/live/1.m3u8", "http://")
        """
        rtscap = RTSCapture(url)
        rtscap.frame_receiver = threading.Thread(target=rtscap.recv_frame, daemon=True)
        rtscap.schemes.extend(schemes)
        if isinstance(url, str) and url.startswith(tuple(rtscap.schemes)):
            rtscap._reading = True
        elif isinstance(url, int):
            # 这里可能是本机设备
            pass

        return rtscap

    def isStarted(self):
        """替代 VideoCapture.isOpened() """
        ok = self.isOpened()
        if ok and self._reading:
            ok = self.frame_receiver.is_alive()
        return ok

    def recv_frame(self):
        """子线程读取最新视频帧方法"""
        while self._reading and self.isOpened():
            ok, frame = self.read()
            if not ok: break
            self._cur_frame = frame
        self._reading = False

    def read2(self):
        """读取最新视频帧
        返回结果格式与 VideoCapture.read() 一样
        """
        frame = self._cur_frame
        self._cur_frame = None
        return frame is not None, frame

    def start_read(self):
        """启动子线程读取视频帧"""
        self.frame_receiver.start()
        self.read_latest_frame = self.read2 if self._reading else self.read

    def stop_read(self):
        """退出子线程方法"""
        self._reading = False
        if self.frame_receiver.is_alive(): self.frame_receiver.join()


if __name__ == '__main__':
    # get camera frame
    # include visible radiation frame and infrared radiation frame
    # using onvif
    reconnecttimes = 3
    for t in range(reconnecttimes): 
        print("init cam ...")
        src_camera_vr = "rtsp://admin:qianding2020@10.39.245.250:554/h265/ch1/main/av_stream"
        src_camera_ir = "rtsp://admin:qianding2020@10.39.245.250:554/h265/ch2/main/av_stream"
        rtscap_vr = RTSCapture.create(src_camera_vr) # visible radiation 
        rtscap_ir = RTSCapture.create(src_camera_ir) # infrared radiation 
        rtscap_vr.start_read()
        rtscap_ir.start_read()
        print("cam init done.")

        n = 0
        errcode = 0
        errtimes = 0
        sleeptime_begin = 0.05
        while rtscap_vr.isStarted() and rtscap_ir.isStarted():
            if errtimes > 4:
                print("reconnect to IPC.")
                break

            n += 1
            print("count: ", n)
            
            if n > 500: # just for test
                break
            
            try:
                # read frame & change data into string
                #ret, frame = cap.read()
                ok1, frame_vr = rtscap_vr.read_latest_frame()
                ok2, frame_ir = rtscap_ir.read_latest_frame()
            except:
                print("get frame err.")
                errtimes += 1
                continue

            try:
                # test
                cv2.imshow("cam_vr", frame_vr)
                cv2.waitKey(10)
                cv2.imshow("cam_ir", frame_ir)
                cv2.waitKey(10)
            except:
                print("imshow or imwrite err.")
                continue

        rtscap_vr.stop_read()
        rtscap_ir.stop_read()
        rtscap_vr.release()
        rtscap_ir.release()

    # 断开连接
    connection.close()
